import { withSSRContext } from "aws-amplify";
import { serializeModel, deserializeModel } from "@aws-amplify/datastore/ssr";
import { LessonLayout } from "../../../../components/LessonLayout";
import { Contributor, Course, Lesson } from "../../../../models";
import { YoutubeEmbed } from "../../../../components/YoutubeEmbed";
import { Text, useBreakpointValue, View, Flex } from "@aws-amplify/ui-react";
import { LessonTableOfContents } from "../../../../components/LessonTableOfContents";
import { LearnMarkdown } from "../../../../components/LearnMarkdown";
import { CoursesRouteLayout } from "../../../../components/CoursesRouteLayout";
import { createCourseTitleUri } from "../../../../utils";
import { useRouter } from "next/router";
import { Fallback } from "../../../../components/Fallback";
import Link from "next/link";
import ArrowRightIconCustom from "../../../../ui-components/ArrowRightIconCustom";
import styles from "./lesson.module.scss";
import { CardLayoutData, Context, MetaInfo } from "../../../../types/models";
import {
GetStaticPaths,
GetStaticPathsResult,
GetStaticPropsContext,
GetStaticPropsResult,
} from "next";
import {
getCardLayoutData,
getCourseAndLessonData,
getCourseContributors,
} from "../../../../lib/getData";
import { ParsedUrlQuery } from "querystring";
export default function LessonPage(data: {
course: Course;
lessons: Lesson[];
currentLesson: Lesson;
contributors: Contributor[];
cardLayoutData: string;
}) {
const showInSidebarBreakpoint = useBreakpointValue({
base: false,
small: false,
medium: false,
large: true,
xl: true,
});
const router = useRouter();
if (router.isFallback) {
return ;
}
const course: Course = deserializeModel(Course, data.course);
const lessons: Lesson[] = deserializeModel(Lesson, data.lessons);
const currentLesson: Lesson = deserializeModel(Lesson, data.currentLesson);
const contributors: Contributor[] = deserializeModel(
Contributor,
data.contributors
);
const cardLayoutData: CardLayoutData[] = JSON.parse(data.cardLayoutData);
const lessonNumber = currentLesson.lessonNumber;
// Lesson page meta data
const metaInfo: MetaInfo = {
title: currentLesson.title,
image: course.image,
description: currentLesson.description,
author: `${contributors
.map((c) => `${c.firstName} ${c.lastName}`)
.join(", ")}`,
};
return (
{currentLesson.youtubeEmbedId && (
)}
{course.title}
{currentLesson.title}
{!showInSidebarBreakpoint && (
)}
{lessonNumber < lessons.length && (
Next
{lessons[lessonNumber].title}
)}
}
sidebarChildren={
}
/>
);
}
interface LessonPageProps {
course: JSON;
lessons: JSON;
currentLesson: JSON;
contributors: JSON;
cardLayoutData: string;
}
interface LessonPageParams extends ParsedUrlQuery {
courseurltitle: string;
lesson: string;
}
export async function getStaticPaths(
context: GetStaticPaths & Context
): Promise> {
const { DataStore } = withSSRContext(context);
const lessons: Lesson[] = await DataStore.query(Lesson);
const courses: Course[] = await DataStore.query(Course, (c: any) =>
c.published("eq", true)
);
// Create object that contains course title, course Id, and the lesson number
const data = courses.map((course) => {
const filteredLessons = lessons.filter(
(lesson) => lesson.lessonCourseLessonId === course.id
);
return filteredLessons.map((lesson) => ({
courseurltitle: course.courseUrlTitle,
courseId: course.id,
lessonNumber: `${lesson.lessonNumber}`,
}));
});
// `data` is an array of arrays so we need to flatten it in order to have the
// correct structure to return the paths
const flatData = data.reduce((acc, currentValue) => {
acc.push(...currentValue);
return acc;
}, []);
return {
paths: flatData.map((e) => ({
params: {
courseurltitle: createCourseTitleUri(e.courseurltitle, e.courseId),
lesson: e.lessonNumber,
},
})),
fallback: false,
};
}
export async function getStaticProps(
context: GetStaticPropsContext & Context
): Promise> {
const courseAndLessonData = await getCourseAndLessonData(context);
if (courseAndLessonData) {
const { lesson: lessonNumber } = context.params as LessonPageParams;
const currentLesson = courseAndLessonData.lessons[Number(lessonNumber) - 1];
const cardLayoutData = await getCardLayoutData(context);
const courseContributors = await getCourseContributors(
context,
(rel) => rel.course.id === courseAndLessonData.course.id
);
if (currentLesson && currentLesson.id) {
return {
props: {
course: serializeModel(courseAndLessonData.course),
lessons: serializeModel(courseAndLessonData.lessons),
currentLesson: serializeModel(currentLesson),
contributors: serializeModel(courseContributors),
cardLayoutData: JSON.stringify(cardLayoutData),
},
};
}
}
return {
notFound: true,
};
}